
class_name UnitProperty
extends Node




## unit 的属性组件
## unit 的各项数据在此组件定义




@export var unit_name: String = ""

## 移动格数与行动优先度
@export var sp: int = 0
@export var priority: int = 0

## 体力相关属性
@export_category("Hp")
@export var hp: int = 0
@export var hp_cycle: int = 0
@export var hp_recover: int = 0
@export var current_hp: int = 0:
	set = set_current_hp,
	get = get_current_hp

## 能量相关属性
@export_category("Ep")
@export var ep: int = 0
@export var ep_cycle: int = 0
@export var ep_recover: int = 0
@export var current_ep: int = 0:
	set = set_current_ep,
	get = get_current_ep

## 抗性
@export_category("Dp")
@export var dp_special: int = 0
@export var dp_ordinary: int = 0

## 攻击相关属性
@export_category("Attack")
@export var ap_ordinary: int = 0
@export var ap_special: int = 0
@export var attack_type: ATTACK_TYPE = ATTACK_TYPE.MELEE
## 攻击长度
@export var attack_length: int = 0
## 攻击盲区(vector2 表示忽略的具体位置 ； int 类型表示忽略的第几步)
@export var attack_ignore: Array = [ Vector2(0, 0) ]
## 攻击范围种类
@export var attack_range_type: ATTACK_RANGE_TYPE = ATTACK_RANGE_TYPE.CROSS

## 组件的装载者
@onready var master: Unit = null
@onready var timer: Timer = $Timer

## 攻击类型
enum ATTACK_TYPE {
	## 近战
	MELEE,
	## 远程
	REMOTE
}

## 攻击距离类型类型
enum ATTACK_RANGE_TYPE {
	## 十字
	CROSS,
	## 范围
	RANGE,
	## 倾斜十字，就是 X 字形
	TILE_CROSS,
	## 倾斜范围，就是菱形
	TILE_RANGE
}

## unit 行动状态
enum ACTION_STATE {
	## 已行动状态
	END,
	## 待机状态
	NONE,
	## 行动中状态
	ACTION
}

## 行动状态
var action_state: ACTION_STATE = ACTION_STATE.NONE

## 攻击机会
var attack_chance: int = 1
## 移动机会
var move_chance: int = 2
## 行动机会
var action_chance: int = 2

## 当前HP恢复进行周期
var current_hp_cycle: int = 0
## 当前EP恢复进行周期
var current_ep_cycle: int = 0




func _ready() -> void:
	master = get_parent()




func _enter_tree() -> void:
	master = get_parent()




# 设置当前 hp
# 传入的参数是计数好之后的值
func set_current_hp(_num: int) -> void:
	if not is_instance_valid(master):
		current_hp = _num
		return
	
	# 如果值与 current_hp 相同就说明是无事发送
	if _num == current_hp:
		return
	
	# 如果是小于，就说明是受伤了
	if _num < current_hp:
		var harm: int = current_hp - _num
		GFloatInfo.show_info(
			"-" + str(harm),
			master.position + Vector2(16, -32),
			0.5,
			Color8(255, 127, 0)
		)
		current_hp = clampi(_num, 0, hp)
	
	# hp 增加
	# 值会限制在最大值以内
	else:
		# 显示恢复值
		var harm: int = _num - current_hp
		GFloatInfo.show_info(
			"+" + str(harm),
			master.position + Vector2(16, -32),
			0.5,
			Color8(0, 255, 127)
		)
		# 防止生命值溢出，使用 clampi 方法进行约束
		current_hp = clampi(_num, 0, hp)
	
	# 判断 unit 挂了没有
	if current_hp < 1:
		get_parent().die(self)




# 返回当前 hp
func get_current_hp() -> int:
	return current_hp




# 设置 ep
func set_current_ep(_num: int) -> void:
	if not is_instance_valid(master):
		current_ep = _num
		return
	
	# 耗蓝
	if _num < current_ep:
		var h = current_ep - _num
		GFloatInfo.show_info(
			"-" + str(h),
			master.position + Vector2(16, -32),
			0.5,
			Color8(0, 127, 255)
		)
	else:
		var h = _num - current_ep
		GFloatInfo.show_info(
			"+" + str(h),
			master.position + Vector2(16, -48),
			0.5,
			Color8(0, 0, 255)
		)
	
	current_ep = clampi(_num, 0, ep)




# 返回当前 ep
func get_current_ep() -> int:
	return current_ep




## 调用时周期 + 1
## HP与EP的自然恢复需要此方法
func cycle(_round_number: int) -> void:
	# 判断 HP 与 EP 是否有消耗
	# 满状态不会增加周期
	# 就是满状态时就会停止周期计数
	if current_hp != hp:
		current_hp_cycle += 1
		if current_hp_cycle >= hp_cycle:
			current_hp += hp_recover
			current_hp_cycle = 0
	
	# 进行等待，防止重叠
	timer.start(0.25)
	await timer.timeout
	
	if current_ep != ep:
		current_ep_cycle += 1
		if current_ep_cycle >= ep_cycle:
			current_ep += ep_recover
			current_ep_cycle = 0




## 被攻击就调用这个方法
## 应该返回一个结果给攻击者
## 应该接受连个参数
## 1. 攻击者 2.伤害值
## 生命应该在这个方法中削减
## 状态：TODO
func under_attack(_attacker: Unit, _harm: Dictionary) -> Dictionary:
	# 最少造成 1 点伤害
	# 让伤害被自己的防御力减免
	var re: int = 0
	if _harm["type"] == "ordinary":
		re = _harm["harm"] - dp_ordinary
	# 特殊伤害按百分比计算
	elif _harm["type"] == "special":
		if dp_special != 0:
			var a = int(100) / int(dp_special)
			var b = _harm["harm"] / a
			re = _harm["harm"] - b
		else:
			re = _harm["harm"]
	_harm["re_harm"] = clampi(re, 1, 255)
	current_hp -= _harm["re_harm"]
	return _harm
